import React, { Component } from 'react'

export default class Tree extends Component {
  state = {
    nodes: []
  };
  static defaultProps = {
    nodes: []
  };
  constructor(props) {
    super(props);

    const nodes = props.nodes;

    function preTreatNodes(nodes, parent) {
      nodes.forEach(item => {
        item._open = false;
        item._match = false;
        item._act = false;
        if (parent) item._parent = parent;
        if (item.children) {
          preTreatNodes(item.children, item);
        }
      });
    }

    preTreatNodes(nodes);

    this.state.nodes = nodes;
  };
  search(value) {
    const nNodes = this.state.nodes.concat();

    function openParents(node) {
      let parent = node._parent;
      if (parent) {
        parent._open = true;
        if (parent._parent) openParents(parent);
      }
    }

    function activeNode(nodes) {
      nodes.forEach(item => {
        if (item.text === value) {
          item._match = true;
          openParents(item);
        } else {
          item._match = false;
        }
        if (item.children) activeNode(item.children)
      });
    }

    activeNode(nNodes);
    
    this.setState({
      nodes: nNodes
    });
  };
  handleNodeClick(node) {
    const _this = this;
    const nNodes = this.state.nodes.concat();

    function clearSelect(nodes) {
      nodes.forEach(item => {
        item._act = false;
        if (item.children) clearSelect(item.children);
      });
    }


    function openOrActNode(nodes) {
      nodes.forEach(item => {
        if (item === node) {
          if (item.children) {
            item._open = !item._open;
          } else {
            clearSelect(nNodes);
            item._act = true;
            if (_this.props.onSelect) _this.props.onSelect(item);
          }
          return false;
        }
        if (item.children) openOrActNode(item.children)
      });
    }

    openOrActNode(nNodes);

    this.setState({
      nodes: nNodes
    });
  };
  render() {
    const _this = this;
    function repeatingNode(node) {
      return node.map((item) => {
        return (
          <div
            className={
              'Tree__node' + 
              (item._open ? ' open' : '') + 
              (item._match ? ' match' : '') +
              (item._act ? ' act' : '')
            }
            key={item.id}>
            <div className="Tree__node_head" onClick={() => {_this.handleNodeClick(item)}}>
              {item.children && <i className="arrow"></i>}
              <p className="name">{item.text}</p>
            </div>
            <div
              className="Tree__node_body">
              { item.children && repeatingNode(item.children) }
            </div>
          </div>
        );
      });
    }
    return (
      <div className="Tree">
        <div className="Tree__search">
          <input
            placeholder="搜索"
            onInput={(e) => {this.search(e.target.value)}}>
          </input>
        </div>
        <div className="Tree_nodes">
          {repeatingNode(this.state.nodes)}
        </div>
      </div>
    );
  }
}